package io.github.lee.jel.ui.main.home

import android.app.Activity
import android.util.Log
import android.widget.LinearLayout
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.Toolbar
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.viewModels
import dagger.hilt.android.AndroidEntryPoint
import io.github.lee.core.ui.BaseFragment
import io.github.lee.core.ui.databinding.ToolbarSimpleCenterTitleBinding
import io.github.lee.core.util.getColor
import io.github.lee.core.util.screenWidth
import io.github.lee.core.util.toDp
import io.github.lee.core.util.toPx
import io.github.lee.core.vm.err.NoMoreDataException
import io.github.lee.core.vm.err.ViewModelException
import io.github.lee.jel.R
import io.github.lee.jel.databinding.FragmentHomeBinding
import io.github.lee.jel.databinding.ItemHomeLatestListBinding
import io.github.lee.jel.databinding.ItemHomePlayingListBinding
import io.github.lee.jel.databinding.LayoutDefaultErrorBinding
import io.github.lee.jel.databinding.LayoutItemHorizontalScrollBinding
import io.github.lee.jel.databinding.LayoutServerEmptyBinding
import io.github.lee.jel.global.theme.ThemeManager
import io.github.lee.jel.ui.add.AddServerActivity
import io.github.lee.jel.ui.detail.ItemDetailActivity
import io.github.lee.jel.ui.list.ItemListActivity
import io.github.lee.repository.jel.data.session
import io.github.lee.repository.jel.domain.Item
import kotlin.math.roundToInt

@AndroidEntryPoint
class HomeFragment : BaseFragment<FragmentHomeBinding, HomeVM>() {
    private val error by lazy {
        LayoutServerEmptyBinding.inflate(layoutInflater).also {
            it.btnText = getString(R.string.txt_add_jellyfin)
            it.setAddClick {
                addServerLauncher.launch(AddServerActivity.intent(mContext))
            }
        }
    }

    private val addServerLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == Activity.RESULT_OK) {
                vm?.fetchRemote(true)
            }
        }

    //===Desc:=============================================================
    companion object {
        fun newInstance(): HomeFragment =
            HomeFragment()
    }

    //===Desc:=============================================================

    override fun onCreateViewModel(): Lazy<HomeVM> =
        viewModels()


    override fun onCreateToolbar(): Toolbar =
        ToolbarSimpleCenterTitleBinding.inflate(layoutInflater)
            .also {
                it.bg = ThemeManager.toolbarColor(mContext)
                it.title = getString(R.string.txt_main_screen)

            }.toolbar

    override fun onCreateEmpty(): ViewDataBinding = error
    override fun showEmpty(e: ViewModelException?) {
        super.showEmpty(e)
        if (e is NoMoreDataException) {
            error.btnText = getString(R.string.txt_retry)
            error.setAddClick {
                vm?.getHomeData()
            }
        } else {
            error.btnText = getString(R.string.txt_add_jellyfin)
            error.setAddClick {
                addServerLauncher.launch(AddServerActivity.intent(mContext))
            }
        }
    }

    override fun onCreateError(): ViewDataBinding =
        LayoutDefaultErrorBinding.inflate(layoutInflater).also {
            it.setRetryClick { vm?.getHomeData() }
        }

    override fun onCreateSuccess(): FragmentHomeBinding =
        FragmentHomeBinding.inflate(layoutInflater).also {
            it.vm = this.vm
        }

    override fun refreshSuccess(hasMore: Boolean?) {
        super.refreshSuccess(hasMore)
        vb?.refresh?.isRefreshing = false
    }
    //===Desc:=============================================================

    override fun onObserved() {
        super.onObserved()
        vm?.homeDataLiveData?.observe(viewLifecycleOwner) {

            if (it.isNullOrEmpty()) {
                return@observe
            }
            vb?.llContent?.removeAllViews()
            it.forEachIndexed { index, pair ->
                val itemList = pair.second
                if (itemList.isNullOrEmpty()) {
                    return@observe
                }

                val viewDataBinding = if (getString(R.string.txt_playing) == pair.first.name) {
                    playingView(pair.first, pair.second)
                } else {
                    latestView(pair.first, pair.second)
                }
                if (null != viewDataBinding) {
                    val params = LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.MATCH_PARENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT
                    )
                    if (index != 0) {
                        params.topMargin = 16.toPx(mContext)
                    }
                    vb?.llContent?.addView(viewDataBinding.root, params)
                }
            }
        }
    }

    override fun onSetViewListener() {
        super.onSetViewListener()
        vb?.refresh?.setOnRefreshListener { vm?.fetchRemote(false) }
    }

    override fun onSetViewData() {
        super.onSetViewData()
        vb?.refresh?.setColorSchemeColors(
            getColor(R.color.main_theme)
        )
        if (vm?.homeDataLiveData?.value.isNullOrEmpty()) {
            vm?.getHomeData()
        } else {
            vm?.homeDataLiveData?.postValue(vm?.homeDataLiveData?.value)
        }
    }

    //===Desc:=============================================================
    private fun playingView(parent: Item, items: List<Item>?): ViewDataBinding? {
        if (items.isNullOrEmpty()) {
            return null
        }
        val root = LayoutItemHorizontalScrollBinding.inflate(layoutInflater)
        root.title = parent.name
        items.forEachIndexed { index, item ->
            val itemPlayingRoot = ItemHomePlayingListBinding.inflate(layoutInflater)
            itemPlayingRoot.item = item
            itemPlayingRoot.host = mContext.session?.host

            val itemWidth = if (screenWidth(mContext).toDp(mContext) < 600) {
                (screenWidth(mContext) * 3 * 1.0F / 4).roundToInt()
            } else if (screenWidth(mContext).toDp(mContext) in 600..839) {
                (screenWidth(mContext) * 1 * 1.0F / 4).roundToInt()
            } else {
                (screenWidth(mContext) * 1 * 1.0F / 5).roundToInt()
            }

            val params = LinearLayout.LayoutParams(
                itemWidth,
                LinearLayout.LayoutParams.WRAP_CONTENT
            )
            when (index) {
                0 -> params.marginStart = 16.toPx(mContext)
                items.size - 1 -> {
                    params.marginStart = 8.toPx(mContext)
                    params.marginEnd = 16.toPx(mContext)
                }

                else -> params.marginStart = 8.toPx(mContext)
            }
            itemPlayingRoot.setPlayClick {
                Log.e("TAG", "Go to play")
            }
            itemPlayingRoot.root.setOnClickListener {
                ItemDetailActivity.start(mContext, item)
            }


            root.llItemContent.addView(itemPlayingRoot.root, params)
        }
        return root
    }

    private fun latestView(parent: Item, items: List<Item>?): ViewDataBinding? {
        if (items.isNullOrEmpty()) {
            return null
        }
        val root = LayoutItemHorizontalScrollBinding.inflate(layoutInflater)
        root.title = getString(R.string.txt_start_latest, parent.name)
        root.setMoreClick {
            ItemListActivity.start(mContext, parent)
        }
        items.forEachIndexed { index, item ->
            val itemLatestRoot = ItemHomeLatestListBinding.inflate(layoutInflater)
            itemLatestRoot.item = item
            itemLatestRoot.host = mContext.session?.host
            val itemWidth = if (screenWidth(mContext).toDp(mContext) < 600) {
                (screenWidth(mContext) * 1.0F / 4).roundToInt()
            } else if (screenWidth(mContext).toDp(mContext) in 600..839) {
                (screenWidth(mContext) * 1 * 1.0F / 8).roundToInt()
            } else {
                (screenWidth(mContext) * 1 * 1.0F / 12).roundToInt()
            }
            val params = LinearLayout.LayoutParams(
                itemWidth,
                LinearLayout.LayoutParams.WRAP_CONTENT
            )
            when (index) {
                0 -> params.marginStart = 16.toPx(mContext)
                items.size - 1 -> {
                    params.marginStart = 8.toPx(mContext)
                    params.marginEnd = 16.toPx(mContext)
                }

                else -> params.marginStart = 8.toPx(mContext)
            }

            itemLatestRoot.root.setOnClickListener {
                ItemDetailActivity.start(mContext, item)
            }
            root.llItemContent.addView(itemLatestRoot.root, params)
        }
        return root
    }
}


